package org.eclipseuseradmin.internal.ui.views;

import java.util.Iterator;

import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.ViewPart;
import org.eclipseuseradmin.internal.ui.RoleRootsRegistry;
import org.eclipseuseradmin.internal.ui.RolesContentProvider;
import org.eclipseuseradmin.internal.ui.RolesLabelProvider;
import org.eclipseuseradmin.internal.ui.UserAdminUiPlugin;
import org.eclipseuseradmin.internal.ui.editors.RoleElementInput;
import org.eclipseuseradmin.ui.BaseRoleElementAdapter;
import org.eclipseuseradmin.ui.IRoleElement;
import org.osgi.service.useradmin.UserAdmin;

public class RolesView extends ViewPart implements ISetSelectionTarget {

	private String id;

	private UserAdmin userAdmin;

	private FilteredTree filteredTree;

	private TreeViewer viewer;

	private Action refreshAction;

	@Override
	public void createPartControl(Composite parent) {

		parent.setLayout(new GridLayout());
		parent.getLayoutData();

		createViewer(parent);
		createActions();
		hookContextMenu();
	}

	private void createViewer(Composite parent) {

		filteredTree = new FilteredTree(parent, SWT.BORDER | SWT.MULTI,
				new PatternFilter());
		viewer = filteredTree.getViewer();
		// viewer = new TreeViewer(parent, SWT.BORDER | SWT.MULTI);
		viewer.setContentProvider(getRolesContentProvider());
		ILabelDecorator decorator = PlatformUI.getWorkbench()
				.getDecoratorManager().getLabelDecorator();
		viewer.setLabelProvider(new DecoratingLabelProvider(
				getRolesLabelProvider(), decorator));
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				handelOpenEditor(event.getSelection());
			}
		});
		viewer.setInput(getTreeRoot());
		getSite().setSelectionProvider(viewer);
	}

	private void createActions() {

		refreshAction = new Action("refresh", UserAdminUiPlugin
				.getImageDescriptor("/icons/refresh.gif")) {
			public void run() {

				handelRefresh();
			}
		};
	}

	private void hookContextMenu() {

		MenuManager menuManager = new MenuManager("#PopupMenu");
		menuManager
				.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
		menuManager.setRemoveAllWhenShown(true);
		menuManager.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {

				fillContextMenu(manager);
			}
		});
		Menu menu = menuManager.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuManager, viewer);
	}

	private void fillContextMenu(IMenuManager manager) {

		manager.add(refreshAction);
		manager.add(new Separator());
	}

	private RoleRootsRegistry getTreeRoot() {

		return getRoleRootsRegistry();
	}

	private void handelRefresh() {

		ISelection selection = viewer.getSelection();
		Iterator selectionItr = ((TreeSelection) selection).iterator();
		while (selectionItr.hasNext()) {
			Object element = selectionItr.next();
			viewer.refresh(element);
		}
	}

	private void handelOpenEditor(ISelection selection) {

		Object object = ((TreeSelection) selection).getFirstElement();
		if (object == null) {
			return;
		}
		IRoleElement roleElement = (IRoleElement) Platform.getAdapterManager()
				.getAdapter(object, IRoleElement.class);
		if (roleElement == null) {
			return;
		}

		IEditorDescriptor editorDescriptor = BaseRoleElementAdapter
				.getDefaultEditor(roleElement);
		if (editorDescriptor == null) {
			return;
		}

		try {
			PlatformUI.getWorkbench().getActiveWorkbenchWindow()
					.getActivePage().openEditor(
							new RoleElementInput(roleElement),
							editorDescriptor.getId());
		} catch (PartInitException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void selectReveal(ISelection selection) {

		viewer.getControl().setRedraw(false);
		viewer.setSelection(selection, true);
		viewer.getControl().setRedraw(true);
	}

	@Override
	public void setFocus() {
		/*
		 * if (filteredTree.getFilterControl() != null) {
		 * filteredTree.getFilterControl().setFocus(); }
		 */}

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {

		id = site.getId();
		super.init(site, memento);
	}

	@Override
	public void dispose() {

		super.dispose();
	}

	private RolesContentProvider getRolesContentProvider() {

		RolesContentProvider provider = new RolesContentProvider(viewer);
		provider.setUserAdmin(getUserAdmin());
		provider.setAdapterManager(getAdapterManager());
		return provider;
	}

	private RolesLabelProvider getRolesLabelProvider() {

		RolesLabelProvider provider = new RolesLabelProvider();
		provider.setEditorRegistry(getEditorRegistry());
		provider.setAdapterManager(getAdapterManager());
		return provider;
	}

	private UserAdmin getUserAdmin() {
		return UserAdminUiPlugin.getUserAdmin();
	}

	private IAdapterManager getAdapterManager() {
		return Platform.getAdapterManager();
	}

	private RoleRootsRegistry getRoleRootsRegistry() {
		return UserAdminUiPlugin.getRoleRootsRegistry();
	}

	private IEditorRegistry getEditorRegistry() {
		return PlatformUI.getWorkbench().getEditorRegistry();
	}

	public String getId() {
		return id;
	}

	public TreeViewer getViewer() {
		return viewer;
	}

}
